﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Data.Entity.Infrastructure;
using System.Reflection;

namespace OpenWeb.Dal.Utils
{

  //<add key="DatabaseInitializerForType CodeFirstDbInitializerDemo.BlogContext,CodeFirstDbInitializerDemo" 
  //   value="CodeFirstDbInitializerDemo.BlogContextCustomInitializer, CodeFirstDbInitializerDemo" />

  // Modello per creare il database via mvc DbContext
  class CreateMyDBIfNotExists<TContext>: IDatabaseInitializer<TContext>
        where TContext : DbContext
{
    public void InitializeDatabase(TContext context)
    {
        if (context.Database.Exists())
        {
            if (!context.Database.CompatibleWithModel(false))
            {
                throw new InvalidOperationException("The model has changed!");
            }
        }
        else
        {
            CreateMyDatabase(context);
        }
    }

    //// Inizializza i dati
    //protected override void Seed(TContext context)
    //{
    //  //Category cat1 = new Category { Id = Guid.NewGuid(), Name = ".NET Framework" };
    //  //context.Categories.Add(cat3);
    //  context.SaveChanges();
    //}
 
    private void CreateMyDatabase(TContext context)
    {
        try
        {
            // Create as much of the database as we can
            context.Database.Create();
            //context.Database.ExecuteSqlCommand("CREATE TABLE GLOBAL_DATA([KEY] VARCHAR(50), [VALUE] VARCHAR(250))");
            // No exception? Don't need a workaround
            // Seed();

            return;
        }
        catch (DataException ex)
        {
          throw;
        }
 
        // Manually create the metadata table
        var conn = ((SqlConnection)context.Database.Connection);
        using (var command = conn.CreateCommand())
        {
            command.CommandText =
            @"
            CREATE TABLE __MigrationHistory (
                MigrationId mediumtext NOT NULL,
                Model mediumblob NOT NULL,
                ProductVersion mediumtext NOT NULL);
 
            ALTER TABLE __MigrationHistory ADD PRIMARY KEY (MigrationId(255));
 
            INSERT INTO __MigrationHistory (
                MigrationId,
                Model,
                ProductVersion)
            VALUES (
                'InitialCreate',
                @Model,
                @ProductVersion);
            ";
            command.Parameters.AddWithValue(
                "@Model",
                GetModel(context));
            command.Parameters.AddWithValue(
                "@ProductVersion",
                GetProductVersion());

            conn.Open();
            command.ExecuteNonQuery();
            conn.Close();
        }

        

    }//fm
 
    private byte[] GetModel(TContext context)
    {
        using (var memoryStream = new MemoryStream())
        {
            using (var gzipStream = new GZipStream(
                memoryStream,
                CompressionMode.Compress))
            using (var xmlWriter = XmlWriter.Create(
                gzipStream,
                new XmlWriterSettings { Indent = true }))
            {
                EdmxWriter.WriteEdmx(context, xmlWriter);
            }
 
            return memoryStream.ToArray();
        }
    }
 
    private string GetProductVersion()
    {
        return typeof(DbContext).Assembly
            .GetCustomAttributes(false)
            .OfType<AssemblyInformationalVersionAttribute>()
            .Single().InformationalVersion;
    }
}
}
